package tweeter;
import java.io.File;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LogParser
{
	public static HashSet<Integer> generateAllEntityIDs(String followersFileDir, String tweetersFileDir)
	{		
		HashSet<Integer> entities = new HashSet<Integer>();
		File followersDirectory = new File(followersFileDir);
		if (false == followersDirectory.exists())
		{
			System.out.println(followersFileDir + " doesn't exist");
			return null;
		}
		if (false == followersDirectory.isDirectory())
		{
			System.out.println(followersFileDir + " is not a directory?");
		}
		String[] followerFiles = followersDirectory.list();
		for (String fileName : followerFiles)
		{
			File followerFile = new File(followersFileDir + "/" + fileName);
			if (0 == followerFile.length())
			{
				System.out.println(followersFileDir + "/" + fileName + " is empty, not adding it!");
				continue;
			}
			// Syntax is <ID>_follower
			String[] fileTokens = fileName.split("_");
			if (2 != fileTokens.length)
			{
				System.out.println("Something's wrong with " + fileName);
			}
			else
			{
				Integer ID = Integer.parseInt(fileTokens[0]);
				entities.add(ID);
			}
		}
		
		File tweetersDirectory = new File(tweetersFileDir);
		if (false == tweetersDirectory.exists())
		{
			System.out.println(tweetersFileDir + " doesn't exist");
			return null;
		}
		if (false == tweetersDirectory.isDirectory())
		{
			System.out.println(tweetersFileDir + " is not a directory?");
		}
		String[] tweeterFiles = tweetersDirectory.list();
		for (String fileName : tweeterFiles)
		{
			File tweeterFile = new File(tweetersFileDir + "/" + fileName);
			if (0 == tweeterFile.length())
			{
				System.out.println(tweetersFileDir + "/" + fileName + " is empty, not adding it!");
				continue;
			}
			// Syntax is <ID>_follower
			String[] fileTokens = fileName.split("_");
			if (2 != fileTokens.length)
			{
				System.out.println("Something's wrong with " + fileName);
			}
			else
			{
				Integer ID = Integer.parseInt(fileTokens[0]);
				entities.add(ID);
			}
		}
		return entities;
	}
	
	public static Map<Integer, HashSet<Integer>> generateSubscriptions(String followersFileDir) throws FileNotFoundException
	{
		Map<Integer, HashSet<Integer>> subscriptions = new HashMap<Integer, HashSet<Integer>>();
		File followersDirectory = new File(followersFileDir);
		if (false == followersDirectory.exists())
		{
			System.out.println(followersFileDir + " doesn't exist");
			return null;
		}
		if (false == followersDirectory.isDirectory())
		{
			System.out.println(followersFileDir + " is not a directory?");
		}
		String[] followerFiles = followersDirectory.list();
		for (String fileName : followerFiles)
		{
			File followerEntry = new File(followersFileDir + "/" + fileName);
			if (0 == followerEntry.length())
			{
				System.out.println(followersFileDir + "/" + fileName + " is empty, not subscriptions for him!");
				continue;
			}
			// Syntax is <ID>_follower
			String[] fileTokens = fileName.split("_");
			if (2 != fileTokens.length)
			{
				System.out.println("Something's wrong with " + fileName);
			}
			else
			{
				Integer ID = Integer.parseInt(fileTokens[0]);
				HashSet<Integer> followerSubscriptions = new HashSet<Integer>();
				Scanner input = new Scanner(followerEntry);
				while (input.hasNextLine())
				{
					// Syntax is <ID>
					Integer followingID = Integer.parseInt(input.nextLine());
					followerSubscriptions.add(followingID);
				}
				input.close();
				subscriptions.put(ID, followerSubscriptions);
			}

		}
		
		return subscriptions;
	}
	
	@SuppressWarnings("unchecked") // TODO: Check why we need this...
	public static ArrayList<Tweet> generateTweets(String tweetersFileDir) throws FileNotFoundException, ParseException
	{
		ArrayList<Tweet> tweets = new ArrayList<Tweet>();

		File tweetsDirectory = new File(tweetersFileDir);
		if (false == tweetsDirectory.exists())
		{
			System.out.println(tweetersFileDir + " doesn't exist");
			return null;
		}
		if (false == tweetsDirectory.isDirectory())
		{
			System.out.println(tweetersFileDir + " is not a directory?");
		}
		String[] tweetFiles = tweetsDirectory.list();
		for (String fileName : tweetFiles)
		{
			File entryTweets = new File(tweetersFileDir + "/" + fileName);
			if (0 == entryTweets.length())
			{
				System.out.println(tweetersFileDir + "/" + fileName + " is empty, no tweets for him!");
				continue;
			}
			// Syntax is <ID>_follower
			String[] fileTokens = fileName.split("_");
			if (2 != fileTokens.length)
			{
				System.out.println("Something's wrong with " + fileName);
			}
			else
			{
				System.out.println("Parsing " + fileName);
				int tweetCounter = 0;
				Integer twitterID = Integer.parseInt(fileTokens[0]);
				Scanner input = new Scanner(entryTweets);
				// Syntax is
				// YYYY-MM-DDTHH:MM:SS+00:00  Tweet
				Pattern tweetPattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})\\+(\\d{2}):(\\d{2})\\s\\s");
				SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//				System.out.println(tweetPattern);
				while ((input.hasNextLine()) && (tweets.size()) < 2000 && (tweetCounter < 5))
				{
					String tweetEntry = input.nextLine();
//					System.out.println(tweetEntry);
					Matcher patternMatcher = tweetPattern.matcher(tweetEntry);
					if (patternMatcher.find())
					{
//						System.out.println("Found the pattern -> " + patternMatcher.groupCount());
						if (8 == patternMatcher.groupCount())
						{
							String date = patternMatcher.group(1) + "-" +
										  patternMatcher.group(2) + "-" +
										  patternMatcher.group(3) + " " +
										  patternMatcher.group(4) + ":" +
										  patternMatcher.group(5) + ":" +
										  patternMatcher.group(6);
							Date tweetDate = dateFormat.parse(date);
							String tweetData = tweetEntry.substring(patternMatcher.group().length()); // Walkaround
							Calendar tweetCalendarDate = new GregorianCalendar();
							tweetCalendarDate.setTime(tweetDate);
							if (tweetCalendarDate.get(Calendar.YEAR) != 2008)
							{
								continue;
							}
							Tweet tweet = new Tweet(twitterID, tweetCalendarDate, tweetData);
							tweets.add(tweet);
							tweetCounter++;
						}
					}
				}
				input.close();
			}
		}
		Collections.sort(tweets);
		return tweets;
	}
}
